package com.campus.client.view;

import com.campus.client.controller.BankController;
import com.campus.client.net.ClientConnector;
import com.campus.common.message.BankRequest;
import com.campus.common.message.BankResponse;
import com.campus.common.vo.BankTransaction;
import com.campus.common.vo.User;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Pair;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Optional;

public class BankFrame {
	private BankController bankController;
    private Label balanceLabel;  
    private Button backButton;
    private TableView<BankTransaction> transactionTable;
    private ObservableList<BankTransaction> transactionList = FXCollections.observableArrayList();

    private User user=new User();
    public User getUser() {return user;}
    public void setUser(String Id,String password,String role) {
        this.user.setId(Id);
        this.user.setPassword(password);
        this.user.setRole(role);
    }


    public void start(Stage primaryStage) throws Exception {
    	bankController = new BankController(new ClientConnector("172.20.10.2", 8888));

        BorderPane root = new BorderPane();
        root.setPadding(new Insets(10));
        root.getStyleClass().add("main-container");

        // 顶部标题栏
        HBox headerBox = new HBox();
        headerBox.getStyleClass().add("header-box");
        headerBox.setAlignment(Pos.CENTER_LEFT);
        headerBox.setPadding(new Insets(10, 15, 10, 15));

        Label titleLabel = new Label("虚拟校园银行 - 学生教师版");
        titleLabel.getStyleClass().add("header-title");

        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);

        backButton = new Button("返回");
        backButton.getStyleClass().add("secondary-button");
        backButton.setOnAction(e -> {
            try {
                back();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        });

        // 交易流水按钮放在右上角
        Button transactionBtn = createStyledButton("查看交易流水");
        transactionBtn.setOnAction(e -> showTransactionPopup());

        headerBox.getChildren().addAll(titleLabel, spacer, transactionBtn, backButton);
        root.setTop(headerBox);

        // 中心内容
        VBox contentBox = new VBox(20);
        contentBox.setPadding(new Insets(20));
        contentBox.setAlignment(Pos.TOP_CENTER);
        contentBox.getStyleClass().add("content-box");

        // 显示余额
        balanceLabel = new Label("当前余额: --");
        balanceLabel.getStyleClass().add("section-title");

        Button queryBtn = createStyledButton("查询余额");
        queryBtn.setOnAction(e -> queryBalance());

        // 充值
        HBox rechargeBox = new HBox(10);
        rechargeBox.setAlignment(Pos.CENTER);
        TextField rechargeField = new TextField();
        rechargeField.setPromptText("输入充值金额");
        Button rechargeBtn = createStyledButton("充值");
        rechargeBtn.setOnAction(e -> {
            try {
                double amt = Double.parseDouble(rechargeField.getText());
                recharge(amt);
            } catch (NumberFormatException ex) {
                showAlert("错误", "请输入有效的金额！", Alert.AlertType.ERROR);
            }
        });
        rechargeBox.getChildren().addAll(new Label("充值:"), rechargeField, rechargeBtn);

        // 开户和销户按钮
        Button createBtn = new Button("开户");
        Button deleteBtn = new Button("销户");
        createBtn.getStyleClass().add("gray-button");
        deleteBtn.getStyleClass().add("gray-button");

        HBox accountBox = new HBox(15);
        accountBox.setAlignment(Pos.CENTER);
        accountBox.getChildren().addAll(createBtn, deleteBtn);

        contentBox.getChildren().addAll(balanceLabel, queryBtn, rechargeBox, accountBox);
        root.setCenter(contentBox);
        
        
        // ====== 开户逻辑 ======
        createBtn.setOnAction(e -> {
            Dialog<Pair<String, String>> dialog = new Dialog<>();
            dialog.setTitle("开户");
            dialog.setHeaderText("请输入初始金额和密码");

            ButtonType createButtonType = new ButtonType("确认开户", ButtonBar.ButtonData.OK_DONE);
            dialog.getDialogPane().getButtonTypes().addAll(createButtonType, ButtonType.CANCEL);

            GridPane grid = new GridPane();
            grid.setHgap(10); grid.setVgap(10); grid.setPadding(new Insets(20,150,10,10));

            TextField balanceField = new TextField();
            balanceField.setPromptText("初始金额");
            PasswordField pwdField = new PasswordField();
            pwdField.setPromptText("密码");

            grid.add(new Label("初始金额:"), 0, 0);
            grid.add(balanceField, 1, 0);
            grid.add(new Label("密码:"), 0, 1);
            grid.add(pwdField, 1, 1);

            dialog.getDialogPane().setContent(grid);

            dialog.setResultConverter(dialogButton -> {
                if (dialogButton == createButtonType) {
                    return new Pair<>(balanceField.getText(), pwdField.getText());
                }
                return null;
            });

            Optional<Pair<String, String>> result = dialog.showAndWait();
            result.ifPresent(pair -> {
                try {
                    double initBalance = Double.parseDouble(pair.getKey());
                    String password = pair.getValue();
                    boolean ok = bankController.openAccount(user.getId(), initBalance, password);
                    if (ok) {
                        showAlert("成功", "开户成功，初始余额: ¥" + String.format("%.2f", initBalance), Alert.AlertType.INFORMATION);
                        queryBalance();
                    } else {
                        showAlert("失败", "开户失败，账户可能已存在", Alert.AlertType.WARNING);
                    }
                } catch (NumberFormatException ex) {
                    showAlert("错误", "请输入有效金额", Alert.AlertType.ERROR);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    showAlert("错误", "开户失败: " + ex.getMessage(), Alert.AlertType.ERROR);
                }
            });
        });

        // ====== 销户逻辑 ======
        deleteBtn.setOnAction(e -> {
            TextInputDialog pwdDialog = new TextInputDialog();
            pwdDialog.setTitle("销户");
            pwdDialog.setHeaderText("请输入密码以确认销户");
            pwdDialog.setContentText("密码：");

            Optional<String> resultPwd = pwdDialog.showAndWait();
            resultPwd.ifPresent(password -> {
                try {
                    boolean ok = bankController.deleteAccount(user.getId(), password);
                    if (ok) {
                        showAlert("成功", "销户成功！", Alert.AlertType.INFORMATION);
                        balanceLabel.setText("当前余额: --");
                    } else {
                        showAlert("失败", "密码错误或账户不存在，销户失败", Alert.AlertType.WARNING);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    showAlert("错误", "销户失败: " + ex.getMessage(), Alert.AlertType.ERROR);
                }
            });
        });
        

        Scene scene = new Scene(root, 600, 400);
        scene.getStylesheets().add(getClass().getResource("/css/style.css").toExternalForm());
        primaryStage.setTitle("虚拟校园银行 - 学生教师版");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // 查询余额
    private void queryBalance() {
        try {
            double balance = bankController.queryBalance(user.getId());
            if (balance >= 0) {
                balanceLabel.setText("当前余额: " + String.format("¥ %.2f", balance));
                showAlert("成功", "查询成功，余额为 " + String.format("¥ %.2f", balance), Alert.AlertType.INFORMATION);
            } else {
                showAlert("失败", "查询失败", Alert.AlertType.ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            showAlert("错误", "查询失败: " + e.getMessage(), Alert.AlertType.ERROR);
        }
    }

    // 充值
    private void recharge(double amount) {
    	TextInputDialog pwdDialog = new TextInputDialog();
        pwdDialog.setTitle("请输入密码");
        pwdDialog.setHeaderText("为了安全，请输入您的账户密码进行验证");
        pwdDialog.setContentText("密码：");

        Optional<String> result = pwdDialog.showAndWait();
        if (result.isPresent()) {
            String password = result.get();
            
    	try {
            boolean ok = bankController.recharge(user.getId(), amount, password);
            if (ok) {
                showAlert("成功", "充值成功，金额: " + amount, Alert.AlertType.INFORMATION);
                queryBalance(); // 刷新余额显示
            } else {
                showAlert("失败", "密码错误，充值失败", Alert.AlertType.ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            showAlert("错误", "充值失败: " + e.getMessage(), Alert.AlertType.ERROR);
        }
        }
    }

 // 弹窗显示交易流水
    private void showTransactionPopup() {
        try {
            List<BankTransaction> list = bankController.queryTransactions(user.getId());
            transactionList.setAll(list);
        } catch (Exception e) {
            e.printStackTrace();
            showAlert("错误", "加载交易流水失败: " + e.getMessage(), Alert.AlertType.ERROR);
            return;
        }

        Stage stage = new Stage();
        stage.setTitle("交易流水");

        TableView<BankTransaction> table = new TableView<>();
        table.setItems(transactionList);
        table.setPrefWidth(450);
        table.setPrefHeight(300);

        TableColumn<BankTransaction, String> typeCol = new TableColumn<>("交易类型");
        typeCol.setCellValueFactory(new PropertyValueFactory<>("type"));
        typeCol.setPrefWidth(100);

        TableColumn<BankTransaction, Double> amountCol = new TableColumn<>("金额");
        amountCol.setCellValueFactory(new PropertyValueFactory<>("amount"));
        amountCol.setPrefWidth(100);

        TableColumn<BankTransaction, Timestamp> timeCol = new TableColumn<>("时间");
        timeCol.setCellValueFactory(new PropertyValueFactory<>("createTime"));
        timeCol.setCellFactory(column -> new TableCell<BankTransaction, Timestamp>() {
            @Override
            protected void updateItem(Timestamp item, boolean empty) {
                super.updateItem(item, empty);
                if (empty || item == null) {
                    setText(null);
                } else {
                    setText(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(item));
                }
            }
        });
        timeCol.setPrefWidth(200);

        table.getColumns().addAll(typeCol, amountCol, timeCol);

        VBox vbox = new VBox(table);
        vbox.setPadding(new Insets(10));

        Scene scene = new Scene(vbox);
        stage.setScene(scene);
        stage.show();
    }


    private Button createStyledButton(String text) {
        Button button = new Button(text);
        button.getStyleClass().add("primary-button");
        return button;
    }

    private void showAlert(String title, String message, Alert.AlertType type) {
        Alert alert = new Alert(type, message, ButtonType.OK);
        alert.setHeaderText(title);
        alert.showAndWait();
    }

    public void back() throws IOException {
        // 获取当前登录窗口的Stage
        Stage passwordChangeStage = (Stage) backButton.getScene().getWindow();

        if(user.getRole().equals("教师")){
            TeacherMainFrame teacherMainFrame = new TeacherMainFrame();
            teacherMainFrame.setUser(user.getId(),user.getPassword(),user.getRole());
            Stage stage = new Stage();
            teacherMainFrame.show(stage);
        }else{
            StudentMainFrame studentMainFrame = new StudentMainFrame();
            studentMainFrame.setUser(user.getId(),user.getPassword(),user.getRole());
            Stage stage = new Stage();
            studentMainFrame.show(stage);
        }

        passwordChangeStage.close();
    }

}

